<template>
  <div class="publish-content-input-wrap">
    <el-input
      v-model="formData.title"
      maxlength="150"
      placeholder="请输入标题"
      class="input-with-select"
      :input-style="{ border: 'none' }"
    >
      <template #prepend>
        <el-select
          v-model="formData.boardId"
          placeholder="请选择主题分类"
          @change="checkCoin"
          style="width: 145px"
        >
          <el-option
              v-for="item in props.totalBarData"
              :key="item.boardId"
              :label="item.boardName"
              :value="item.boardId">
          </el-option>
        </el-select>
      </template>
    </el-input>
    <div class="textarea-wrap">
      <div class="textarea-box">
        <el-input
          ref="textarea"
          id="textareaRef"
          class="textarea not-shadow"
          v-model="formData.content"
          type="textarea"
          maxlength="300"
          placeholder="请输入内容"
          rows="5"
          resize="none"
          @blur="onTextareaBlur"
          @input="onInput"
          @focus="onTextareaFocus"
          @click="onClickInput"
        />
        <div
          v-if="showTextareaModel"
          class="textarea-model flex-y"
          @click.stop="onChangeTextareaStatus"
        >
          <span>请输入内容</span>
          <span class="mt16">#可选择话题，也可新建话题</span>
          <span v-if="coinDisPlay" class="mt16">
            价格不能低于 1 佰茵币，您有{{userStore.userInfo.byCoin}}佰茵币
            {{userStore.userInfo.byCoin === 0 ? '佰茵币不足，暂不能悬赏求助': ''}}
          </span>
          <span v-if="false">
            30天后如果您仍未设置最佳答案，版主有权代为您选择
          </span>
        </div>
      </div>
      <div class="public-btn flex-yc" v-if="coinDisPlay && userStore.userInfo.byCoin !== 0">
        悬赏价格:
        <el-input-number v-model="formData.byCoin" :precision="0" :min="1" :max="userStore.userInfo.byCoin" :controls="false"></el-input-number>
        佰茵币
      </div>
      <ul
        class="huati-list"
        v-if="isShowHuatiModal"
        @mouseenter="onMouseenterHT(true)"
        @mouseleave="onMouseenterHT(false)"
      >
        <li
          v-for="(item, i) in huatiList"
          :key="item.id"
          @click.stop="onClickHuatiItem(item)"
        >
          {{ item.name }}
        </li>
      </ul>
    </div>
    <div class="other-wrap">
      <div class="inner-img-box">
        <div class="each-img-box" v-for="(item, index) in uploadData" :key="item.fileName + index">
          <div class="upload-progress-box" v-if="parseInt(item.percent) !== 100">
            <el-progress :percentage="item.percent" :show-text="false" color="#409eff" />
          </div>
          <el-image
              style="width: 100%; height: 100%"
              v-if="item.filePath"
              :src="item.filePath"
              :zoom-rate="1.2"
              :max-scale="7"
              :min-scale="0.2"
              :preview-src-list="showImgData"
              :initial-index="index"
              fit="cover"
          />
          <el-icon class="each-delete-icon" @click="deleteUpload(index, uploadData)"><CircleClose /></el-icon>
        </div>
      </div>
      <div class="file-img-box">
        <div class="each-file-box" v-for="(item, index) in uploadFileData">
          <div class="inner-file-name">{{item.fileName}}</div>
          <div class="file-progress-box">
            <div class="progress-box" v-if="parseInt(item.percent) !== 100">
              <el-progress :percentage="item.percent" :show-text="true" color="#409eff" />
            </div>
            <div class="success-box" v-else>
              <el-icon color="rgba(43, 164, 113, 1)"><SuccessFilled /></el-icon>
              <div>上传成功</div>
            </div>
          </div>
          <div class="delete-box" @click="deleteUpload(index, uploadFileData, false)">删除</div>
        </div>
      </div>
      <div class="link-img-box" v-if="formData.netLink">
        <div class="link-dec-icon-box">
          <img src="@/assets/images/board/url-link.png" alt="">
        </div>
        <div class="link-text-box">{{formData.netLink}}</div>
        <div class="delete-box" @click="formData.netLink = ''">删除</div>
      </div>
    </div>
    <div class="flex-xbt fatie-handle-wrap">
      <div class="flex-yc iconfont-wrap">
        <el-tooltip class="item" effect="dark" content="添加图片" placement="bottom-start">
          <el-upload
              :limit="12"
              accept=".jpg,.jpeg,.png,.pdf,.JPG,.JPEG,.BMP"
              ref="upload"
              :http-request="onUpload"
              :before-upload="beforeUpload"
              :on-success="onUploadSuccess"
          >
            <i class="iconfont icon-tupian bold"></i>
          </el-upload>
        </el-tooltip>
        <el-tooltip class="item" effect="dark" content="添加附件" placement="bottom-start">
          <el-upload
              :limit="12"
              ref="uploadFile"
              :http-request="onUploadFile"
              :on-success="onUploadSuccess"
          >
            <i class="iconfont icon-tiezi bold"></i>
          </el-upload>
        </el-tooltip>
        <el-tooltip class="item" effect="dark" content="添加链接" placement="bottom-start">
          <i class="iconfont icon-lianjie bold" @click="onAddLink"></i>
        </el-tooltip>

<!--        <i class="iconfont icon-huati" @click="onClickHuatiIcon"></i>-->
<!--        <i class="iconfont icon-xuanshang"></i>-->
      </div>
      <div class="flex-yc">
        <el-dropdown class="el-icon--left" @command="chooseTemplate">
          <span class="a-link">
            发帖模板
            <el-icon class="el-icon--right">
              <arrow-down />
            </el-icon>
          </span>
          <template #dropdown>
            <el-dropdown-menu>
              <el-dropdown-item v-for="(i, x) in boardTemplate" :command="{title: i.title, content: i.content}" :key="i.id">{{i.title}}</el-dropdown-item>
            </el-dropdown-menu>
          </template>
        </el-dropdown>
        <el-button type="primary" @click="addNewData">发布</el-button>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ElInput, ElMessageBox, ElUpload, UploadRequestOptions } from 'element-plus'
import {
  reqCreateHuati,
  reqGetHuatiList,
  reqUploadImage,
  getBoardTemplate,
  reqUploadFile,
  saveTopic
} from "@/pages/forum/api/huati.ts";
import { reactive, ref, defineProps, onMounted } from 'vue'
import {LoadBoardList, articleForm, uploadFileType, boardTemplate} from "@/pages/forum/types/loadBoard";
import {MsgConfirm, MsgError, MsgSuccess, MsgWarn} from "@/utils/utils.ts";
import { useUserStore } from '@/store/modules/user.ts'
const userStore = useUserStore()
import {Obj} from "@/types/common";
const showTextareaModel = ref(true);
const isShowHuatiModal = ref<boolean>(false)
let mouseIsOnHuatiBox = false
//发布Boolean锁
let createDataFlag = ref<boolean>(true);

//图片上传数组
let uploadData = reactive<uploadFileType[]>([]);
//上传图片锁
let uploadImgFlag = ref<boolean>(true);
//附件上传数组
let uploadFileData = reactive<uploadFileType[]>([]);
//文件锁
let uploadFileFlag = ref<boolean>(true);
let showImgData = reactive<string[]>([]);
//发布模版list
let boardTemplate = reactive<boardTemplate[]>([]);
let cursorPosition = 0
let huatiKeywords = ''
let keywordStart = 0
const huatiList = ref([]);
let coinDisPlay = ref<Boolean>(false);
let controller:Object | null = new AbortController();
//分类数据
let props = defineProps<{totalBarData: LoadBoardList[]}>();
let formData = reactive<articleForm>({
  pBoardId: 0,
  boardId: undefined,
  topicIds: [],
  title: '',
  content: '',
  images: [],//图片
  attachment: [],//文件
  netLink: '',
  integral: '',
  editorType: 1,
  summary: '',
  byCoin: undefined,
})
const textarea = ref<InstanceType<typeof ElInput>>()

// 点击input上面的蒙版
const onChangeTextareaStatus = () => {
  inputSetCursorPosition(cursorPosition)
  showTextareaModel.value = false
}

// 失去焦点
const onTextareaBlur = () => {
  if (formData.content.trim() === '') {
    showTextareaModel.value = true
    formData.topicIds = [];
  }
  if (!mouseIsOnHuatiBox) {
    isShowHuatiModal.value = false
  }
}
// 得到焦点
const onTextareaFocus = () => {
  textarea.value.ref.selectionStart = formData.content.length
}

// 点击input框
const onClickInput = () => {
  isShowHuatiModal.value = false
  onInput()
}

// 点击话题图标
const onClickHuatiIcon = async () => {
  // reqGetHuatiList(formData.textarea)
  onChangeTextareaStatus()
  getHuatiList()
}

// 鼠标移入移出
const onMouseenterHT = (val: boolean) => {
  mouseIsOnHuatiBox = val
}

//点击话题内容
const onClickHuatiItem = async (val: Object) => {
  onAddInputVal(val)
  showTextareaModel.value = false
  isShowHuatiModal.value = false
  mouseIsOnHuatiBox = false
}

// 向input添加数据
const onAddInputVal = (val: Object) => {

  let str1 = formData.content.substring(0, keywordStart)
  let str3 = formData.content.substring(
    cursorPosition,
    formData.content.length,
  )
  str1 = /#$/.test(str1) ? str1 : str1 + '#'
  str3 = /^#/.test(str3) ? str3 : '#' + str3
  formData.content = str1 + val.name + str3
  if (formData.topicIds.findIndex(item => item === val.id) == -1) {
    formData.topicIds.push(val.id);
  }
  console.log(formData, '####')
}

// 输入文字时触发
const onInput = async () => {
  cursorPosition = inputCursorPosition()
  const char = '#'
  const re = new RegExp(char + '(?!.*' + char + ')', 'g')
  const str = formData.content.substring(0, cursorPosition)
  keywordStart = str.search(re)
  const keywordResult = str.substring(keywordStart, cursorPosition)
  const keyword = keywordResult.substring(1)
  if (keywordStart !== -1) {
    if (keywordResult === '#') {
      keywordStart = cursorPosition
      huatiKeywords = ''
    } else if (keyword) huatiKeywords = keyword
    getHuatiList(huatiKeywords)
  } else {
    keywordStart = cursorPosition
    huatiKeywords = ''
  }
}

// 获取光标位置
const inputCursorPosition = () => {
  return document.getElementById('textareaRef').selectionStart
}
// 设置光标位置
const inputSetCursorPosition = (index) => {
  const input: HTMLInputElement = document.getElementById('textareaRef');
  if (input.setSelectionRange) {
    input.focus()
    input.setSelectionRange(index, index)
  } else if (input.createTextRange) {
    const range = input.createTextRange()
    range.collapse(true)
    range.moveEnd('character', index)
    range.moveStart('character', index)
    range.select()
  }
}

// 获取话题列表
const getHuatiList = async (keyword: string) => {
  const { data } = await reqGetHuatiList(keyword)
  if (data.length > 0) {
    huatiList.value = data
    isShowHuatiModal.value = true
  } else {
    isShowHuatiModal.value = false
    keywordStart = cursorPosition
  }
}

//文件校验
function beforeUpload(file):boolean {
  const {name, size} = file;
  const suffix = name.substring(name.lastIndexOf('.'));
  const validSuffix = ['.jpg', '.jpeg', '.png', '.pdf', '.JPG', '.JPEG', '.BMP'];
  let message = '';
  // 最多不超过1G
  if (Number(size) > 1024 * 1024 * 1024) {
    message = `${name}大小超过1GB，无法上传`;
  }
  if (Number(size) === 0) {
    message = `${name}是一个空文件，无法上传`;
  }
  if (!validSuffix.includes(suffix)) {
    message = '只能上传指定格式的文件';
  }
  if (message) {
    MsgError(message);
    return false;
  }
  return true;
}
//删除文件
function deleteUpload(index, originData, imgFlag:boolean = true):void {
  MsgConfirm('确认删除么?', () => {
    controller.abort();
    console.log(controller, '111')
    originData.splice(index, 1);
    if (imgFlag) {
      showImgData.splice(index, 1);
    }
    console.log(originData, 'delete')
  })
}
// 上传图片
const onUpload = async (options: UploadRequestOptions) => {
  uploadImgFlag.value = false;
  if (controller.signal.aborted) {
    controller = null;
    controller = new AbortController();
  }
  const reqData = { file: options.file };
  uploadData.push({
    fileName: reqData.file.name,
    percent: 0,
    fileSize: reqData.file.size,
    fileType: reqData.file.type,
    filePath: ''
  })
  let resp = await reqUploadImage(reqData, (uploadFile) => {
    uploadData[(uploadData.length !== 0) ? uploadData.length - 1 : 0].percent = (uploadFile.loaded / uploadFile.total * 100).toFixed(1);
  }, controller)
  if (resp.code !== 0) {
    uploadData.pop();
    uploadImgFlag.value = true;
    return MsgError(resp.msg || '图片上传失败')
  }
  else {
    uploadData[(uploadData.length !== 0) ? uploadData.length - 1 : 0].filePath = resp.data;
    showImgData.push(resp.data);
    MsgSuccess('上传成功');
    uploadImgFlag.value = true;
    onUploadSuccess();
  }
}
//上传附件
const onUploadFile = async (options: UploadRequestOptions) => {
  uploadFileFlag.value = false;
  if (controller.signal.aborted) {
    controller = null;
    controller = new AbortController();
  }
  const reqData = { file: options.file };
  uploadFileData.push({
    fileName: reqData.file.name,
    percent: 0,
    fileSize: reqData.file.size,
    fileType: reqData.file.type,
    filePath: ''
  })
  let resp = await reqUploadFile(reqData, (uploadFile) => {
    uploadFileData[(uploadFileData.length !== 0) ? uploadFileData.length - 1 : 0].percent = (uploadFile.loaded / uploadFile.total * 100).toFixed(1);
  }, controller)
  if (resp.code !== 0) {
    uploadFileData.pop();
    uploadFileFlag.value = true;
    return MsgError(resp.msg || '附件上传失败')
  }
  else {
    console.log(resp, 'success')
    uploadFileData[(uploadFileData.length !== 0) ? uploadFileData.length - 1 : 0].filePath = resp.data;
    console.log(uploadFileData, 'uploadFileDataurl---')
    MsgSuccess('上传成功');
    uploadFileFlag.value = true;
    onUploadSuccess();
  }
}
// 清空上传缓存
const upload = ref<InstanceType<typeof ElUpload>>()
const onUploadSuccess = () => {
  upload.value.clearFiles() //上传成功之后清除历史记录**加粗样式**
}
//类型选择
function checkCoin(val) {
  if (props.totalBarData.find((item) => item.boardId === val).boardName === '悬赏求助') {
    coinDisPlay.value = true;
  } else {
    coinDisPlay.value = false;
  }
}
//获取模版
async function getBoardTemplateData () {
  let result = await getBoardTemplate();
  if (!result || result.code !== 200) return MsgError(result?.msg || '获取模版失败');
  result.data.list.map((i, index) => {
    boardTemplate.push({
      id: i.id,
      content:i.content,
      title: i.title
    })
  })
}
function chooseTemplate(value) {
  formData.title = value.title;
  formData.content = value.content;
}
const onAddLink = () => {
  ElMessageBox.prompt('请输入上传的链接', '', {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    inputPattern: /^(?:(?:https?|ftp):\/\/)?(?:www\.)?[a-zA-Z0-9-]+(?:\.[a-zA-Z]{2,})+(?:\/[\w-]*)*(?:\?[a-zA-Z0-9-._~:/?#[\]@!$&'()*+,;=%]*)?(?:#[a-zA-Z0-9-._~:/?#[\]@!$&'()*+,;=%]*)?$/,
    inputErrorMessage: '格式不正确',
  }).then(async ({ value }) => {
    formData.netLink = value;
  })
}
//提交
async function addNewData() {
  console.log(formData, 'before')
  if (!uploadImgFlag.value || !uploadFileFlag.value) {
    return MsgWarn('请上传完成后发布!');
  }
  if(!formData.boardId) return MsgError('请选择主题分类');
  if(!formData.title) return MsgError('请填写标题');
  if(!formData.content) return MsgError('请填写内容');
  //boolean锁，防止重复提交
  if (createDataFlag.value) {
    formData.images = uploadData.slice(0, 1);
    formData.attachment = uploadFileData.slice(0, 1);
    console.log(formData, 'submit')
    createDataFlag.value = false;
    let resData = await saveTopic(formData);
    if (!resData || resData.code !== 200) return MsgError(resData?.msg || '发布失败');
    console.log(resData)
    if (resData.code === 200) {
      clearData();
      MsgSuccess('发布成功');
    }
  }
}
function clearData() {
  formData.boardId = undefined;
  formData.title = '';
  formData.content = '';
  formData.images = [];
  formData.attachment = [];
  formData.netLink = '';
  formData.topicIds = [];
  formData.byCoin = undefined;
  uploadData = [];
  uploadFileData = [];
}
onMounted(() => {
  getBoardTemplateData();
})
</script>

<style scoped lang="scss">
.publish-content-input-wrap {
  padding: 16px 28px;
  margin-top: 20px;
  background-color: #fff;
  border-radius: 4px;

  .input-with-select {
    height: 50px;
    margin-bottom: 13px;
    border: none;

    :deep {
      .el-select,
      .el-select__wrapper {
        height: 50px;
        background-color: #fff;
        border: none;

        span,
        .el-icon {
          color: $primary;
        }
      }

      .el-input__wrapper,
      .el-input {
        border: none;
      }
    }
  }
  .fatie-handle-wrap {
    margin-top: 18px;
    :deep(.el-upload-list) {
      display: none;
    }
    .iconfont-wrap {
      i {
        font-size: 24px;
        color: $primary;
        margin-right: 20px;
        cursor: pointer;
        &.bold {
          font-weight: bold;
        }
      }
    }
  }

  .other-wrap {
    padding-top: 20px;
    width: 100%;
    .inner-img-box {
      width: 100%;
      display: flex;
      justify-content: flex-start;
      align-items: center;
      flex-wrap: wrap;
      gap: 10px;
      .each-img-box {
        width: 12%;
        aspect-ratio: 1 / 1;
        border-radius: 4px;
        background: rgba(217, 217, 217, 1);
        position: relative;
        display: flex;
        justify-content: center;
        align-items: center;
        .upload-progress-box {
          width: 90%;
          height: 100%;
          position: absolute;
          z-index: 2;
          .el-progress {
            width: 100%;
            height: 100%;
            .el-progress-circle {
              width: 90%!important;
              height: 90%!important;
            }
          }
        }
        .each-delete-icon {
          font-size: 80%;
          color: rgba(58, 172, 227, 1);
          position: absolute;
          right: 1%;
          top: 1%;
          z-index: 3;
          &:hover {
            cursor: pointer;
          }
        }
        .el-image__inner {
          width: 100%;
          height: 100%;
          display: block;
        }
      }
    }
    .file-img-box {
      width: 100%;
      margin-top: 20px;
      .each-file-box {
        display: flex;
        justify-content: flex-start;
        align-items: center;
        .inner-file-name {
          font-weight: 400;
          font-size: 14px;
          color: rgba(0,0,0,0.9);
          text-align: left;
        }
        .file-progress-box {
          width: 20%;
          .success-box {
            display: flex;
            justify-content: flex-start;
            align-items: center;
            margin-left: 10%;
            i {
              font-size: 14px;
            }
            div {
              margin-left: 10px;
              font-size: 12px;
            }
          }
          .progress-box {
            margin-left: 10%;
          }
        }
        .delete-box {
          font-size: 12px;
          color: rgba(0, 82, 217, 1);
          &:hover {
            cursor: pointer;
          }
        }
      }
    }
    .link-img-box {
      display: flex;
      justify-content: flex-start;
      align-items: center;
      margin-top: 20px;
      .link-dec-icon-box {
        width: 14px;
        height: 14px;
        img {
          display: block;
          width: 100%;
          height: 100%;
        }
      }
      .link-text-box {
        font-weight: 400;
        font-size: 14px;
        color: #3670ED;
        margin-left: 10px;
        overflow: hidden;
        white-space: nowrap;
        text-overflow: ellipsis;
      }
      .delete-box {
        margin-left: 20px;
        font-size: 12px;
        color: rgba(0, 82, 217, 1);
        &:hover {
          cursor: pointer;
        }
      }
    }
  }
}

.textarea-wrap {
  border: 1px solid $borderCol;
  border-radius: 4px;
  position: relative;

  .textarea-box {
    position: relative;
    overflow: hidden;
  }

  .textarea {
    height: 120px;
  }

  .textarea-model {
    position: absolute;
    inset: 0;
    z-index: 1;
    padding: 16px 15px;
    font-size: 14px;
    font-weight: 400;
    color: #a9abb1;
    background-color: #fff;

    span + span {
      margin-top: 6px;
    }

    .mt16 {
      margin-top: 16px;
    }
  }

  .public-btn {
    padding: 4px 16px 8px;
    font-size: 14px;
    font-weight: 400;
    color: $primary;

    .btn {
      margin-right: 20px;
    }

    .el-input-number {
      width: 60px!important;
      margin: 0 10px;
      color: #000;
      border: 1px solid $primary;
      border-radius: 4px;
    }
  }

  .huati-list {
    padding: 0 1px;
    background-color: #fff;
    box-shadow: 0 0 3px 0 rgba(0, 0, 0, 0.2);
    position: absolute;
    left: 10px;
    top: 30px;
    overflow-y: scroll;
    overflow-x: hidden;
    max-height: 200px;
    max-width: 300px;
    z-index: 10;

    li {
      white-space: nowrap;
      overflow: hidden;
      padding: 10px;
      color: #333;
      cursor: pointer;
      font-size: 14px;
      &:hover,
      &.active {
        background-color: rgba(58, 172, 227, 0.1);
      }
    }
  }
}
</style>
